﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AteneoLibriBusinessLogic.Entities;
using AteneoLibri.DomainObject;
using System.Collections.ObjectModel;

namespace AteneoLibri.Account
{
    public partial class Messages : System.Web.UI.Page
    {

        User _Me = null;
        User otherUser = null;
        Guid seller = new Guid();
        Guid purchaser = new Guid();
        Guid saleId = new Guid();
        ObservableCollection<MessageInfo> _messages = new ObservableCollection<MessageInfo>();
        Book book = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            _Me = Utility.HttpSessionManager.GetWebUser();                       

            if (_Me != null)
            {
                string idSale = Request.QueryString[0];
                saleId = new Guid(idSale);
                string otherUserId = Request.QueryString[1];

                string purchaserId = Request.QueryString["PurchaseUserId"];
                string sellerId = Request.QueryString["SellerUserId"]; 

                using (wsAteneoLibri.AteneoLibriServiceClient service = new wsAteneoLibri.AteneoLibriServiceClient())
                {
                    /* Recupero il titolo del libro a partire dalla vendita */
                    book = service.getBookByIdSale(saleId);
                    lblBookTitle.Text = book.Title;

                    otherUser = service.getUserById(new Guid(otherUserId));
                    List<Message> conversations = new List<Message>();                    

                    bool iAmSeller = purchaserId != null && !purchaserId.Equals("");
                    bool iAmPurchaser = sellerId != null && !sellerId.Equals("");

                    if (iAmSeller) // vuol dire che io sono il venditore
                    {

                        seller = _Me.IdUser;
                        purchaser = otherUser.IdUser;
                    }
                    if (iAmPurchaser) // vuol dire che io sono l'acquirente
                    {
                        seller = otherUser.IdUser;
                        purchaser = _Me.IdUser;
                    }

                    conversations = service.getMessagesBetweenSellerPurchaser(seller, purchaser).Where(x => x.SaleId == saleId).ToList();


                    _messages = LoadMessages(conversations);

                    BindDataIntoDataList();


                    if (iAmPurchaser) // se sono io l'acquirente non devo vedere il pannello di messa in vendita
                    {
                        pnlSoldTo.Visible = false;
                    }


                    // Se la end-date della Sale è stata settata, vuol dire che ho venduto il libro, per cui rimuovo il pannello che serve per mettere il libro a venduto e metto il pannello di congratulazioni
                    bool isBookSold = service.getSalesByBookId(book.IdBook).Where(x => x.EndDate != null).Count() > 0;
                    bool iBoughtTheBook = service.getSalesByUserId(_Me.IdUser).Where(x => x.BookId == book.IdBook && x.EndDate != null && (x.SoldTo.HasValue && x.SoldTo.Value == true)).Count() > 0;

                    if (book.IsDeleted.HasValue && book.IsDeleted.Value)
                    {
                        pnlWarning.Visible = true;
                        if (iAmSeller)
                        {
                            lblWarning.Text = "Hai cancellato il libro dal sistema!";
                        }
                        else
                        {
                            lblWarning.Text = "Il libro è stato cancellato dal sistema!";
                        }
                        
                        pnlSoldTo.Visible = false; // nascondo il pannello per mettere il libro a venduto
                    }    
               
                    if (isBookSold) // se il libro è stato venduto cambio i pannelli
                    {

                        if (iBoughtTheBook) // controllo se è stato venduto a me (sono io che effettivamente ho comprato il libro)
                        {
                            pnlSuccess.Visible = true;
                            lblSuccess.Text = "Congratulazioni, hai acquistato questo libro!";
                        }
                        else
                        {
                            pnlWarning.Visible = true;
                            lblWarning.Text = "Questo libro è stato venduto!";
                        }

                        if (iAmSeller) // vuol dire che il libro è stato venduto e l'ho venduto io
                        {
                            pnlWarning.Visible = false;
                            pnlSoldTo.Visible = false;

                            pnlSuccess.Visible = true;
                            lblSuccess.Text = "Congratulazioni, hai venduto questo libro!";
                        }

                    }
                    
                     
                }

            }
            else
            {
                // Redirect per sessione scaduta
                Response.Redirect("~/Logout.aspx");
            }
        }

        private void BindDataIntoDataList()
        {
            dlMessages.DataSource = _messages.OrderBy(x => x.Date).ToList();
            dlMessages.DataBind();
        }

        private ObservableCollection<MessageInfo> LoadMessages(List<Message> conversations)
        {
            ObservableCollection<MessageInfo> messages = new ObservableCollection<MessageInfo>();

            foreach (var item in conversations)
            {
                MessageInfo msg = new MessageInfo();

                if (item.WriteBy.Value != null)
                {
                    msg.Author = getAuthorName(item.WriteBy.Value);
                }
                else
                {
                    msg.Author = "Unknown";
                }
                
                msg.TextMessage = item.TextMessage;
                msg.Date = item.Date;

                messages.Add(msg);
            }

            return messages;
        }

        private string getAuthorName(Guid writeBy)
        {
            using (wsAteneoLibri.AteneoLibriServiceClient service = new wsAteneoLibri.AteneoLibriServiceClient())
            {
                User user = service.getUserById(writeBy);
                return user.Username;
            }
        }

        protected void btnSendMessage_Click(object sender, EventArgs e)
        {
            Message message = new Message();

            message.IdMessage = Guid.NewGuid();
            message.UserIdSeller = seller;
            message.UserIdPurchaser = purchaser;
            message.Date = DateTime.Now;
            message.SaleId = saleId;
            message.WriteBy = _Me.IdUser;

            message.TextMessage = txtResponseMessage.Text.Trim();

            using (wsAteneoLibri.AteneoLibriServiceClient service = new wsAteneoLibri.AteneoLibriServiceClient())
            {
                bool result = service.insertMessage(message);

                if (result)
                {
                    MessageInfo mInfo = new MessageInfo();

                    mInfo.Author = getAuthorName(message.WriteBy.Value);
                    mInfo.TextMessage = message.TextMessage;
                    mInfo.Date = message.Date;

                    this._messages.Add(mInfo);

                    BindDataIntoDataList();

                }
                /* TODO gestire l'invio delle mail ad entrambe le parti */
                NotifyMessageToBothUser();
            }

            txtResponseMessage.Text = "";
        }

        private void NotifyMessageToBothUser()
        {
            string role = "";

            if (_Me.IdUser == seller)
                role = "SellerUserId";
            else
                role = "PurchaseUserId";

            // Colui che scrive il messaggio
            Utility.Mail.MailSender senderMail = new Utility.Mail.MailSender();
            senderMail.SendMail(_Me.Email, "Hai inviato un messaggio per " + book.Title + "!", "Hai inviato un messaggio all'utente <b>" + otherUser.Username + "</b>. <br /><i>" + txtResponseMessage.Text.Trim() + "</i>" + "<br /><br />", true);

            string link = System.Configuration.ConfigurationManager.AppSettings["webSiteURL"] + "/Account/Messages.aspx?IdSale=" + saleId + "&" + role + "=" + _Me.IdUser;

            Utility.Mail.MailSender recieverMail = new Utility.Mail.MailSender();
            recieverMail.SendMail(otherUser.Email, "Hai ricevuto un messaggio per " + book.Title + "!", "Hai ricevuto un messaggio dall'utente <b>" + _Me.Username + "</b>. <br /><i>" + txtResponseMessage.Text.Trim() + "</i>" + "<br /><br />" + "<a href='" + link + "'>Clicca qui per rispondere!</a>", true);
        }

        protected void btnClear_Click(object sender, EventArgs e)
        {
            txtResponseMessage.Text = "";
        }

        protected void btnSoldBook_Click(object sender, ImageClickEventArgs e)
        {
            using (wsAteneoLibri.AteneoLibriServiceClient service = new wsAteneoLibri.AteneoLibriServiceClient())
            {
                /*
                 *  Per mettere a venduto il libro devo recuperare le vendite che hanno come bookId quello selezionato
                 *  A questo punto setto la end date con la data attuale ed aggiorno tutte le vendite
                 *  Questa operazione scatena la comunicazione a tutti gli interessati che questo libro è stato venduto
                 */

                /*
                 * Per notificare la vendita ad una data persona devo accedere alla conversazione e mettere a venduto il libro
                 * In questo modo sono sicuro di aver venduto esattamente a quella persona
                 * In più devo notificare a tutti gli altri acquirenti che il libro è stato venduto ad altri
                 * Settare la end date a tutte le vendite relative a quel libro
                 */
                List<Sale> sellsList = new List<Sale>();
                List<User> purchasersList = new List<User>();
                if (book != null)
                {
                    sellsList = service.getSalesByBookId(book.IdBook);
                    if (sellsList.Count() > 0)
                    {
                        foreach (var item in sellsList)
                        {
                            item.EndDate = DateTime.Now;
                            if (item.IdSale.ToString().Equals(saleId.ToString()))
                            {
                                item.SoldTo = true;
                            }
                            else
                            {
                                item.SoldTo = false;
                            }

                            //service.setEndDate(item, DateTime.Now);
                            service.updateSale(item);
                            purchasersList.Add(service.getUserIdByIdSale(item.IdSale));
                        }

                        sendEmailToPurchasers(purchasersList);

                        pnlSoldTo.Visible = false;

                        pnlSuccess.Visible = true;
                        lblSuccess.Text = "Congratulazioni, hai appena venduto questo libro!";
                    }
                    else
                    {
                        pnlWarning.Visible = true;
                        lblWarning.Text = "Non puoi mettere a venduto il libro in quanto non sono state ricevute richieste di acquisto per lo stesso!";
                    }

                    // Potrei nascondere la sezione per inviare i messaggi
                }
            }
        }

        private void sendEmailToPurchasers(List<AteneoLibriBusinessLogic.Entities.User> purchasersList)
        {
            foreach (var user in purchasersList)
            {
                try
                {
                    Utility.Mail.MailSender mailSender = new Utility.Mail.MailSender();
                    mailSender.SendMail(user.Email, "Cambiato lo stato del libro.", "Il proprietario del libro " + book.Title + " ha venduto il libro.", true);

                }
                catch (Exception)
                {
                    throw;
                }
            }
        }
    }
}